/*
 * Copyright (C) 2010 Fred Barrie This program is free software: you can
 * redistribute it and/or modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version. This program is distributed
 * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details. You should have received
 * a copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
package org.aergia.vinny.database;

import java.sql.Connection;
import java.util.Collection;

import org.aergia.vinny.core.ApiResult;
import org.aergia.vinny.core.enums.DayOfWeek;
import org.aergia.vinny.database.pojo.Card;
import org.aergia.vinny.database.pojo.Location;
import org.aergia.vinny.database.pojo.OperatingHours;
import org.aergia.vinny.database.pojo.Organization;
import org.aergia.vinny.database.pojo.Scan;
import org.aergia.vinny.database.pojo.Service;
import org.aergia.vinny.database.pojo.ServiceType;
import org.aergia.vinny.database.pojo.Skill;
import org.aergia.vinny.database.pojo.SkillRate;
import org.aergia.vinny.database.pojo.VinnyOption;
import org.aergia.vinny.database.pojo.VinnyRole;
import org.aergia.vinny.database.pojo.VinnyUser;
import org.aergia.vinny.database.pojo.Volunteer;
import org.aergia.vinny.database.pojo.VolunteerGroup;
import org.aergia.vinny.database.pojo.Workstation;

/**
 * @author fred
 */
public interface Database {

	/**
	 * @param card
	 * @return the result of adding the record to the database
	 */
	ApiResult<Card> addCard(Card card);

	/**
	 * @param group
	 * @return the result of adding the group to the database
	 */
	ApiResult<VolunteerGroup> addGroup(VolunteerGroup group);

	/**
	 * @param location
	 * @return the result of adding the location to the database
	 */
	ApiResult<Location> addLocation(Location location);

	/**
	 * @param operatingHours
	 * @return the result of adding the operating hours to the database
	 */
	ApiResult<OperatingHours> addOperatingHours(OperatingHours operatingHours);

	/**
	 * @param organization
	 * @return the result of adding the organization
	 */
	ApiResult<Organization> addOrganization(Organization organization);

	/**
	 * @param role
	 * @return the result of adding the role to the database
	 */
	ApiResult<VinnyRole> addRole(VinnyRole role);

	/**
	 * Add a scan record to the database.
	 * 
	 * @param card
	 * @param date
	 * @return the result of adding the record to the database
	 */
	ApiResult<Scan> addScan(Scan scan);

	/**
	 * @param service
	 */
	ApiResult<Service> addService(Service service);

	/**
	 * @param serviceType
	 * @return the result of adding the serviceType
	 */
	ApiResult<ServiceType> addServiceType(ServiceType serviceType);

	/**
	 * @param skill
	 */
	ApiResult<Skill> addSkill(Skill skill);

	/**
	 * @param skillRate
	 */
	ApiResult<SkillRate> addSkillRate(SkillRate skillRate);

	/**
	 * @param newUser
	 * @return
	 */
	ApiResult<VinnyUser> addUser(VinnyUser newUser);

	/**
	 * @param volunteer
	 * @return the result of adding the volunteer
	 */
	ApiResult<Volunteer> addVolunteer(Volunteer volunteer);

	/**
	 * @param workstation
	 * @return the result of adding the workstation
	 */
	ApiResult<Workstation> addWorkstation(Workstation workstation);

	/**
	 * @param deleteUser
	 * @return the result of deleting the user
	 */
	ApiResult<VinnyUser> deleteUser(VinnyUser deleteUser);

	/**
	 * @param volunteer
	 * @return
	 */
	ApiResult<Volunteer> deleteVolunteer(Volunteer volunteer);

	/**
	 * Get the Card for this card number.
	 * 
	 * @param cardNumber
	 * @return the Card for the specified card number or NULL
	 */
	ApiResult<Card> getCard(String cardNumber);

	/**
	 * @return a list of cards, it maybe empty
	 */
	Collection<? extends Card> getCards();

	Connection getConnection();

	/**
	 * @param groupName
	 * @param location
	 * @return
	 */
	ApiResult<VolunteerGroup> getGroup(String groupName, Location location);

	/**
	 * @return the defined groups
	 */
	Collection<? extends VolunteerGroup> getGroups();

	/**
	 * @param id
	 * @return location
	 */
	ApiResult<Location> getLocation(int id);

	/**
	 * @param string
	 * @return the result of looking up the location
	 */
	ApiResult<Location> getLocation(String string);

	Collection<? extends Location> getLocations();

	Collection<? extends OperatingHours> getOperatingHours();

	/**
	 * Get the operating hours for the specified day.
	 * 
	 * @param day
	 * @return the operating hours for the specified day
	 */
	ApiResult<OperatingHours> getOperatingHours(DayOfWeek day);

	/**
	 * @param parameterName
	 * @return the vinny option for the parameterName
	 */
	ApiResult<VinnyOption> getOption(String parameterName);

	/**
	 * @return get options
	 */
	Collection<? extends VinnyOption> getOptions();

	/**
	 * @param name
	 * @return the result of getting the organization
	 */
	ApiResult<Organization> getOrganization(String name);

	/**
	 * @return all organizations
	 */
	Collection<Organization> getOrganizations();

	/**
	 * @param permission
	 * @return the vinny role or an error
	 */
	ApiResult<VinnyRole> getRole(String permission);

	Collection<? extends VinnyRole> getRoles();

	/**
	 * @return list of scans maybe empty
	 */
	Collection<? extends Scan> getScans();

	/**
	 * @return a list of services
	 */
	Collection<? extends Service> getServices();

	/**
	 * @param name
	 * @param location
	 * @return the requested service type or an error
	 */
	ApiResult<ServiceType> getServiceType(String name, Location location);

	/**
	 * @return list of all service types
	 */
	Collection<? extends ServiceType> getServiceTypes();

	/**
	 * Get the skill with the specified description.
	 * 
	 * @param string
	 * @return the skill with this description
	 */
	ApiResult<Skill> getSkill(String description);

	/**
	 * Get the skill rate for the specified skill.
	 * 
	 * @param skill
	 * @return the skill rate for this skill
	 */
	ApiResult<SkillRate> getSkillRate(Skill skill);

	Collection<? extends SkillRate> getSkillRates();

	Collection<? extends Skill> getSkills();

	/**
	 * Return all unapproved scans
	 * 
	 * @return unapproved scans can be empty
	 */
	Collection<Service> getUnapprovedServices();

	/**
	 * Return all unmatched scans.
	 * 
	 * @return unmatched scans can be empty
	 */
	Collection<Scan> getUnmatchedScans();

	/**
	 * Get the Vinny User with this user name.
	 * 
	 * @param userName
	 * @return the VinnyUser with the specified name or NULL
	 */
	ApiResult<VinnyUser> getUser(String userName);

	Collection<? extends VinnyUser> getUsers();

	Collection<VinnyUser> getUsers(String inRole);

	/**
	 * Get the Volunteer with this volunteer ID.
	 * 
	 * @param id
	 * @return the Volunteer with this volunteer ID or NULL.
	 */
	ApiResult<Volunteer> getVolunteer(int id);

	/**
	 * @return collection of volunteers can be empty
	 */
	Collection<? extends Volunteer> getVolunteers();

	/**
	 * @param group
	 * @return get volunteers
	 */
	Collection<Volunteer> getVolunteers(VolunteerGroup group);

	/**
	 * @param id
	 * @return the result of trying to find the workstation
	 */
	ApiResult<Workstation> getWorkstation(int id);

	/**
	 * @param name
	 * @param location
	 * @return the requested workstation or an error
	 */
	ApiResult<Workstation> getWorkstation(String name, Location location);

	/**
	 * @return list of all workstations
	 */
	Collection<? extends Workstation> getWorkstations();

	/**
	 * @param location
	 * @return the list of workstations
	 */
	Collection<? extends Workstation> getWorkstations(Location location);

	/**
	 * @return
	 */
	boolean isInitialized();

	/**
	 * Save the card to the database.
	 * 
	 * @param card
	 * @return the result of saving the card.
	 */
	ApiResult<Card> saveCard(Card card);

	/**
	 * @param group
	 * @param user
	 * @return the result of saving the group
	 */
	ApiResult<VolunteerGroup> saveGroup(VolunteerGroup group);

	/**
	 * @param newHours
	 * @return the result of saving the operating hours
	 */
	ApiResult<OperatingHours> saveOperatingHours(OperatingHours newHours);

	ApiResult<VinnyOption> saveOption(VinnyOption option);

	/**
	 * @param scan
	 */
	ApiResult<Scan> saveScan(Scan scan);

	/**
	 * @param service
	 */
	ApiResult<Service> saveService(Service service);

	/**
	 * @param serviceType
	 * @return the result of saving the serviceType
	 */
	ApiResult<ServiceType> saveServiceType(ServiceType serviceType);

	/**
	 * @param skillRate
	 * @return the result of saving the skill rate
	 */
	ApiResult<SkillRate> saveSkillRate(SkillRate skillRate);

	/**
	 * @param saveUser
	 * @return the result of saving the user.
	 */
	ApiResult<VinnyUser> saveUser(VinnyUser saveUser);

	/**
	 * Save the volunteer to the database.
	 * 
	 * @param volunteer
	 * @return the result of saving the volunteer.
	 */
	ApiResult<Volunteer> saveVolunteer(Volunteer volunteer);

	/**
	 * @param workstation
	 * @return the result of saving the workstation
	 */
	ApiResult<Workstation> saveWorkstation(Workstation workstation);

	/**
	 * @param option
	 */
	void setOption(VinnyOption option);

}
